﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MedicWave.Visualization3d
{
    public partial class WidgetScatterplot3D : UserControl
    {
        /// <summary>
        /// A copy of the entire plot data.
        /// </summary>
        InternalScatterplotData m_PlotData;



        public WidgetScatterplot3D()
        {
            InitializeComponent();

            this.MouseWheel += new MouseEventHandler(WidgetScatterplot3D_MouseWheel);
        }

      

        #region External api

        /// <summary>
        /// Sets data to plot, using default settings.
        /// </summary>
        /// <param name="plotData">PlotData object containing data to plot.</param>
        public void SetData(ScatterplotData plotData)
        {
            m_PlotData = InternalScatterplotData.FromRawData(plotData);



            //display loading message/lock plot
            plot3DView.IsLoading = true;

            plot3DView.SetData(m_PlotData);
            plot3DView.Focus();
            if (m_PlotData.PlotType == ScatterplotType.BiPlot)
            {
                dataZoomScrollBar.Enabled = false;
            }
            else
            {
                dataZoomScrollBar.Enabled = true;
            }
        }

        /// <summary>
        /// Sets data to plot using specified settings.
        /// </summary>
        /// <param name="plotData">PlotData object containing data to plot</param>
        /// <param name="plotSettings">Plot settings</param>
        public void SetData(ScatterplotData plotData, ScatterplotSettings plotSettings)
        {
            m_PlotData = InternalScatterplotData.FromRawData(plotData);

            if(plotSettings.CorrelationThreshold==0)
                plotSettings.CorrelationThreshold = 0.5f;
            if (plotSettings.BackgroundColor.A != 255)
                plotSettings.BackgroundColor = Color.FromArgb(40, 40, 40);
            
            m_PlotData.Settings=plotSettings;


            //display loading message/lock plot
            plot3DView.IsLoading = true;
            //compute data subset
            plot3DView.SetData(m_PlotData);
            plot3DView.Focus();
            if (m_PlotData.PlotType == ScatterplotType.BiPlot)
            {
                dataZoomScrollBar.Enabled = false;
            }
            else
            {
                dataZoomScrollBar.Enabled = true;
            }
        }

        /// <summary>
        /// Sets new settings for current plot.
        /// </summary>
        /// <param name="newSettings">New settings</param>
        public void SetPlotSettings(ScatterplotSettings newSettings)
        {
            ///no data to plot
            if (m_PlotData == null) return;

            m_PlotData.Settings = newSettings;


            //display loading message/lock plot
            plot3DView.IsLoading = true;

            plot3DView.UpdatePlot(newSettings);
            plot3DView.Focus();



        }


        /// <summary>
        /// Returns a PlotSettings structure with settings for current plot. Requires PlotData to be set.
        /// </summary>
        /// <returns>Plot settings</returns>
        public ScatterplotSettings GetCurrentSettings()
        {
            if (m_PlotData == null) throw new NoPlotDataException();    //no plot data, throw an exception


            return m_PlotData.Settings;
        }

        /// <summary>
        /// Renders plot to a bitmap.
        /// </summary>
        /// <param name="bitmapWidth">Bitmap width in pixels</param>
        /// <param name="bitmapHeight">Bitmap height in pixels</param>
        /// <param name="printerFriendlyColors">If this parameter is 'true' then
        /// printer-friendly colors are used (white background, black text etc.)</param>
        /// <returns>Bitmap containing the plot</returns>
        public Bitmap RenderPlotToBitmap(int bitmapWidth, int bitmapHeight, bool printerFriendlyColors)
        {
            Bitmap bmp = plot3DView.RenderToBitmap(bitmapWidth, bitmapHeight, printerFriendlyColors);


            return bmp;
        }

        
        #endregion

        void WidgetScatterplot3D_MouseWheel(object sender, MouseEventArgs e)
        {
            //zoom in/out
            int value = dataZoomScrollBar.Value + (int)(e.Delta / 120);
            if (value >= dataZoomScrollBar.Maximum)
                value = dataZoomScrollBar.Maximum - 1;
            else if (value < 0)
                value = 0;
            dataZoomScrollBar.Value = value;
        }


        #region Fullscreen

        private bool isFullscreen = false;
        private Control windowedOwner = null;
        private Form fullscreenForm = null;
        private Point windowedLocation;
        private Size windowedSize;
        private Button exitButton;
        private void GoFullscreen()
        {
            isFullscreen = true;
            windowedOwner = plot3DView.Parent;
            windowedLocation = plot3DView.Location;
            windowedSize = plot3DView.Size;
            fullscreenForm = new Form();

            fullscreenForm.WindowState = FormWindowState.Maximized;
            fullscreenForm.FormBorderStyle = FormBorderStyle.None;
            fullscreenForm.SuspendLayout();


            fullscreenForm.Controls.Add(this.plot3DView);
            exitButton = new Button();

            exitButton.AutoSize = true;
            exitButton.FlatStyle = FlatStyle.Flat;
            exitButton.Text = "Exit Fullscreen";
            
            exitButton.Click += new EventHandler(exitButton_Click);
            fullscreenForm.Controls.Add(exitButton);
            exitButton.BringToFront();
            fullscreenForm.ResumeLayout(true);
            fullscreenForm.Load += new EventHandler(fullscreenForm_Load);
            fullscreenForm.MouseWheel += new MouseEventHandler(WidgetScatterplot3D_MouseWheel);
            fullscreenForm.Show();
        }

        void exitButton_Click(object sender, EventArgs e)
        {
            GoWindowed();
        }

        void fullscreenForm_Load(object sender, EventArgs e)
        {
            plot3DView.Size = fullscreenForm.ClientSize;
            plot3DView.Location = new Point(0, 0);
            exitButton.Location = new Point(fullscreenForm.ClientSize.Width -exitButton.Size.Width-5, 10);

        }
        private void GoWindowed()
        {
            isFullscreen = false;

            plot3DView.Size = windowedSize;
            plot3DView.Location = windowedLocation;
            windowedOwner.Controls.Add(plot3DView);

            fullscreenForm.Close();

            Refresh();
        }
        #endregion 


        private void btsSaveScreen_Click(object sender, EventArgs e)
        {
            SaveScreenshot();
        }

        internal void SaveScreenshot()
        {
            SaveFileSettingsForm saveForm = new SaveFileSettingsForm();
            if (saveForm.ShowDialog() == DialogResult.OK)
            {
                if (saveFileDialogPic.ShowDialog() == DialogResult.OK)
                {
                    plot3DView.RenderToBitmap(saveForm.GetWidth(), saveForm.GetHeight(),
                        saveForm.GetPrinterColors()).Save(saveFileDialogPic.FileName, System.Drawing.Imaging.ImageFormat.Png);
                }
            }
        }

        private void btnSettings_Click(object sender, EventArgs e)
        {
            if( m_PlotData!= null)
            {
                ScatterplotSettingsForm settingsForm = new ScatterplotSettingsForm();
                if( settingsForm.ShowDialog(m_PlotData.Settings, m_PlotData.PlotType == ScatterplotType.BiPlot)== DialogResult.OK)
                {
                    ScatterplotSettings settingFromDialog = new ScatterplotSettings();
                    settingFromDialog.PlotProjectionType = settingsForm.GetOrtographicProjSet();                    
                    settingFromDialog.ShowCaseNames = settingsForm.GetShowNames();
                    settingFromDialog.ShowGrid = settingsForm.GetShowGridSet();
                    settingFromDialog.ShowLegend = settingsForm.GetShowLegend();
                    settingFromDialog.Subtitle = settingsForm.GetSubtitle();
                    settingFromDialog.Title = settingsForm.GetTitle();
                    settingFromDialog.XLabel = settingsForm.GetXLabel();
                    settingFromDialog.YLabel = settingsForm.GetYLabel();
                    settingFromDialog.ZLabel = settingsForm.GetZLabel();
                    settingFromDialog.CorrelationThreshold = settingsForm.GetCoorelationThreshold();
                    settingFromDialog.PrinterFriendlyColors = settingsForm.GetPrinterFriendlSet();
                    settingFromDialog.BackgroundColor = settingsForm.GetBackGroundColor();
                    settingFromDialog.DrawInnerPlanes = settingsForm.GetDrawInnerPlanes();
                    if( settingFromDialog.PlotProjectionType != m_PlotData.Settings.PlotProjectionType || 
                        settingFromDialog.ShowCaseNames != m_PlotData.Settings.ShowCaseNames ||
                        settingFromDialog.ShowGrid != m_PlotData.Settings.ShowGrid ||
                        settingFromDialog.ShowLegend != m_PlotData.Settings.ShowLegend ||
                        !settingFromDialog.Subtitle.Equals(m_PlotData.Settings.Subtitle) ||
                        !settingFromDialog.Title.Equals(m_PlotData.Settings.Title) ||
                        !settingFromDialog.XLabel.Equals(m_PlotData.Settings.XLabel) ||
                        !settingFromDialog.YLabel.Equals(m_PlotData.Settings.YLabel) ||
                        !settingFromDialog.ZLabel.Equals(m_PlotData.Settings.ZLabel) ||
                        settingFromDialog.CorrelationThreshold != m_PlotData.Settings.CorrelationThreshold ||
                        settingFromDialog.PrinterFriendlyColors!=m_PlotData.Settings.PrinterFriendlyColors || 
                        settingFromDialog.DrawInnerPlanes != m_PlotData.Settings.DrawInnerPlanes ||
                        settingFromDialog.BackgroundColor != m_PlotData.Settings.BackgroundColor)
                    {
                        m_PlotData.Settings = settingFromDialog;
                        plot3DView.UpdatePlot(settingFromDialog);
                    }
                }
            }
        }

       

        bool m_bSupressZoomEvent = false;

        private void dataZoomScrollBar_ValueChanged(object sender, EventArgs e)
        {
            if (m_PlotData.PlotType!= ScatterplotType.BiPlot)
            {
                if (!m_bSupressZoomEvent)
                    plot3DView.SetDataZoom(dataZoomScrollBar.Value);
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            plot3DView.ResetCamera();
        }

        private void btnFullScreen_Click(object sender, EventArgs e)
        {
            GoFullscreen();
        }

        private void cameraZoomScrollBar_ValueChanged(object sender, EventArgs e)
        {
            plot3DView.SetCameraZoom(cameraZoomScrollBar.Value);
        }

        /// <summary>
        /// Sets correct zoom on the slider
        /// </summary>
        /// <param name="zoom">Data zoom: 0-no zoom, 100-maximum zoom</param>
        internal void SetZoom(int zoom)
        {
            if (zoom < dataZoomScrollBar.Minimum || zoom >= dataZoomScrollBar.Maximum) return; //invalid parameter

            m_bSupressZoomEvent = true;
            this.dataZoomScrollBar.Value = zoom;
            m_bSupressZoomEvent = false;
        }
    }
}
